/**
 * 
 */
package ProtoSimulator;

import java.io.*;
import java.net.*;
import java.lang.Thread;
import java.net.URL;
import java.util.HashMap;
import java.util.Random;

import org.apache.log4j.Logger;

/**
 * @author jjmb
 *
 */
public class Notification {
	private static final String CLASS_NAME = Notification.class.getName();
    public static final Logger logger = Logger.getLogger(CLASS_NAME);
    
	private static HashMap<Long, String> notifications = new HashMap<Long, String>();
	private static Random random = new Random();
	private boolean complete = false;
	private boolean busy = true;

	  // Use this to get an notification
	   public synchronized Object getNotification(int id) {
		   logger.trace("Getting notification for ID, " + id);
		   while (busy == true) {
			    try {
			    	wait();
			    } 
			    catch (InterruptedException e) {
			    }
			}
		   busy = true;
		   notifyAll();
		   logger.trace("Returning, " + notifications.get(id).toString());

		   return notifications.get(id);
	   }
	   
	   // use this to get all notifications
	   public synchronized Object getAllNotifications() {
		   logger.trace("Getting all notifications(busy = " + busy + ")");
		   while (busy == true) {
			    try {
			    	wait();
			    } 
			    catch (InterruptedException e) {
			    }
			}
		   	busy = true;
		   	notifyAll();
			logger.trace("Returning, " + notifications.toString() + " (busy = " + busy +")");
			return notifications;
	   }
		
	   // use this to set an notification
	   public synchronized void setNotification(String notificationData) {
		   Long id = random.nextLong();
		   logger.trace("Setting event (" + notificationData + ") for ID " + id + " (busy = " + busy + ")");
		   while (busy == true) {
		        try {
		        	wait();
		        } 
		        catch (InterruptedException e) {
		        }
		   }
		   busy = true;
		   // busy = false;
		   notifications.put(id, notificationData);
		   logger.trace("Size of notification hash table after putting values " + notifications.size() + " (busy = " + busy +")");
		   busy = false;
		   notifyAll();
	   }
	   
	   // use this to delete an notification
	   public synchronized void deleteNotification(int id) {
		   logger.trace("Deleting notification with ID = " + id + " (busy = " + busy + ")");
		 
		   while (busy == true) {
		        try {
		        	wait();
		        } 
		        catch (InterruptedException e) {
		        }
		   }
		   busy = true;
		   notifications.remove(id);
		   logger.trace("Size of notification hash table after removing values " + notifications.size());
		   busy = false;
		   notifyAll();
	   }
	   
	   // use this to get the notification count
	   public synchronized int getNotificationCount() {
		   logger.trace("Getting notification count (busy = "+busy+")");
		   while (busy == true) {
		        try {
		        	wait();
		        } 
		        catch (InterruptedException e) {
		        }
		   }
		   notifyAll();
		   logger.trace("Returning notification count, " + notifications.size() + " (available = " + busy +")");
		   return notifications.size();
	   }
	   
	   public synchronized boolean hasNotifications() {
		   logger.trace("Determining if notifications exist (busy = "+busy+")...");
		   boolean hasNotifications = false;
			
			busy = false;

		   
		   if(notifications.size() > 0) {
			   hasNotifications = true;
		   }
		   
		   notifyAll();
		   
		   return hasNotifications;
	   }
	   
		public synchronized boolean isComplete() {
			logger.trace("Size of notifications is, " + notifications.size());
			while (notifications.size() > 0) {
		        try {
		        	wait();
		        } 
		        catch (InterruptedException e) {
		        }
			}
			complete = true;
			busy = false;
			notify();
			logger.trace("Retuning complete status " + complete);		
			return complete;
		}
}